package de.hft_stuttgart.dsa.ctt.model;

import java.util.List;

/**
 * This matrix is used within the Pre-Processing steps. Do not use this matrix
 * to assign courses to.
 * 
 * @author Matthias Huber
 */
public class CourseLectureCompetitionMatrix extends AbstractMatrix {

	public CourseLectureCompetitionMatrix(List<Period> periods, List<Room> rooms, ProblemInstance problemInstance) {
		super(rooms, periods);

		if (null != rooms && null != periods) {
			periodRoomMatrix = new Integer[periods.size()][rooms.size()];
			// initialized with the number of lectures of all courses so that
			// after calculation
			// the figures represent the number of assignable lectures. Example:
			// one timeslot is initialized with numberOfLectures = 160 and
			// afterwards 3 courses with 12 lectures aggregated cannot be
			// assigned to this timeslot because
			// of UnavailablilityConstraints, so the number of this timeslot is
			// 148 which means that 148 lectures can be assigned to this
			// timeslot. IMPORTANT: it's true you cannot really assign 3
			// lectures of a course to the same timeslot but it gets a better
			// variants for the numbers. This fact is handled during the update
			// of the matrix.
			int totalNumberOfLectures = 0;
			for (Course course : problemInstance.getAllCourses().values()) {
				totalNumberOfLectures += course.getNumberOfLectures();
			}
			initializeMatrix(totalNumberOfLectures);
		} else {
			throw new RuntimeException("Rooms or Periods must not be null");
		}
	}

	private void initializeMatrix(int numberOfCourses) {
		for (int i = 0; i < periodRoomMatrix.length; i++) {
			for (int j = 0; j < periodRoomMatrix[i].length; j++) {
				periodRoomMatrix[i][j] = new Integer(numberOfCourses);
			}
		}
	}

	public void updateSingleTimeslot(int unavailabilityPeriod, int numberOfLectures) {
		// just update all rooms within the timeslot
		for (int i = 0; i < periodRoomMatrix[unavailabilityPeriod].length; i++) {
			periodRoomMatrix[unavailabilityPeriod][i] = ((Integer) periodRoomMatrix[unavailabilityPeriod][i]).intValue() - numberOfLectures;
		}
	}

	public CourseLectureCompetitionMatrix clone() throws CloneNotSupportedException {
		CourseLectureCompetitionMatrix object = (CourseLectureCompetitionMatrix) super.clone();
		object.periodRoomMatrix = new Object[periods.size()][rooms.size()];
		for (int i = 0; i < object.periodRoomMatrix.length; i++) {
			for (int j = 0; j < object.periodRoomMatrix[i].length; j++) {
				object.periodRoomMatrix[i][j] = new Integer((Integer) periodRoomMatrix[i][j]).intValue();
			}
		}
		return object;
	}

}
